﻿// Date: 24.08.11

// Revision 3 (31.01.12)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NOVA.Sound;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using NOVA.Sound;

namespace NOVA.Scenery
{
    /// <summary>
    /// Creates a sound object for the scene.
    /// </summary>
    public class SoundObject : ITransformable, IAudioEmitter
    {
        #region Members
        Vector3 m_position;
        Quaternion m_orientation;
        Vector3 m_scale;
        string m_type;
        BoundingBox m_boundingBox;
        string m_name;
        Matrix m_controllerMatrix;
        bool m_bHasController;
        Vector3 m_forward;
        Vector3 m_up;
        Vector3 m_velocity;
        SoundEffect m_soundEffect;
        SoundEffectInstance m_soundInstance;
        bool m_bIsActive;
        int m_iID;
        #endregion

        #region Properties

        public int ID { get { return m_iID; } }

        public Vector3 Position
        {
            get
            {
                return m_position;
            }
            set
            {
                m_position = value;
            }
        }

        public Quaternion Orientation
        {
            get
            {
                return m_orientation;
            }
            set
            {
                m_orientation = value;
            }
        }

        public Vector3 Scale
        {
            get
            {
                return m_scale;
            }
            set
            {
                m_scale = value;
            }
        }

        public string Type
        {
            get
            {
                return m_type;
            }
            set
            {
                m_type = "Sound";
            }
        }

        public BoundingBox BoundingBox
        {
            get { return m_boundingBox; }
        }

        public string Name
        {
            get
            {
                return m_name;
            }
            set
            {
                m_name = value;
            }
        }

        public Matrix ControllerMatrix
        {
            get
            {
                return m_controllerMatrix;
            }
            set
            {
                m_controllerMatrix = value;
            }
        }

        public bool HasController
        {
            get
            {
                return m_bHasController;
            }
            set
            {
                m_bHasController = value;
            }
        }

        public Vector3 Forward
        {
            get { return m_forward; }
        }

        public Vector3 Up
        {
            get { return m_up; }
        }

        public Vector3 Velocity
        {
            get { return m_velocity; }
        }

        public SoundEffect SoundEffect
        {
            get { return m_soundEffect; }
            set { m_soundEffect = value; }
        }

        public bool IsLooped
        {
            get { return m_soundInstance.IsLooped; }
            set { m_soundInstance.IsLooped = value; }
        }

        public float Pan
        {
            get { return m_soundInstance.Pan; }
            set { m_soundInstance.Pan = value; }
        }

        public float Pitch
        {
            get { return m_soundInstance.Pitch; }
            set { m_soundInstance. Pitch = value; }
        }

        public float Volume
        {
            get { return m_soundInstance.Volume; }
            set { m_soundInstance.Volume = value; }
        }

        public SoundState State
        {
            get { return m_soundInstance.State; }
        }

        internal bool IsActive
        {
            get { return m_bIsActive; }
            set { m_bIsActive = value; }
        }

        internal SoundEffectInstance Instance
        {
            get { return m_soundInstance; }
            set { m_soundInstance = value; }
        }
        #endregion

        #region Constructor

        /// <summary>
        /// Creates a sound object for the scene.
        /// </summary>
        public SoundObject(Vector3 position, SoundEffect soundEffect, bool looped)
        {
            m_position = position;

            m_soundEffect = soundEffect;

            m_soundInstance = soundEffect.CreateInstance();

            m_soundInstance.IsLooped = looped;

            m_bIsActive = false;

            m_iID = Core.GetNextNodeID();
        }
        #endregion

        #region Public Methods

        /// <summary>
        /// Plays the sound object.
        /// </summary>
        public void Play()
        {
            m_soundInstance.Play();
            m_bIsActive = true;
        }

        /// <summary>
        /// Plauses the sound object.
        /// </summary>
        public void Pause()
        {
            m_soundInstance.Pause();
        }

        /// <summary>
        /// Resumes the sound object.
        /// </summary>
        public void Resume()
        {
            m_soundInstance.Resume();
        }

        /// <summary>
        /// Stops the sound object.
        /// </summary>
        public void Stop()
        {
            m_soundInstance.Stop();
            m_bIsActive = false;
        }

        public void Dispose()
        {
            // Don't dispose the sound objects to avoid an XNA, 
            // because the SoundEffect seems to be static.
            //m_soundEffect.Dispose();
            
            m_soundInstance.Dispose();
        }
        #endregion
    }
}
